// /src/app/middlewares/error.middleware.js
'use strict';

const { logger, color, emailTool } = require('../utils');
const config = require('../config');

// 从配置中获取告警接收人（支持多个邮箱）
const ALERT_EMAILS = config.environment.alert?.receiveEmails?.split(',') || [];
const NODE_ENV = config.environment.nodeEnv;

/**
 * 全局异常处理中间件
 * 功能：捕获接口500服务端错误（发告警邮件）、过滤4xx客户端错误（仅日志）
 * 说明：邮件发送用非阻塞方式（不await），避免影响接口响应速度
 */
const errorHandler = (err, req, res, next) => {
    // 1. 过滤4xx客户端错误（如参数错误、权限不足等，不需要告警）
    if (err.statusCode && err.statusCode >= 400 && err.statusCode < 500) {
        logger.warn(
            `${color.yellow}⚠️  客户端请求错误：${req.method} ${req.path} | 错误：${err.message}${color.reset}`,
            { metadata: {} },
        );
        return res.status(err.statusCode).json({
            code: err.statusCode,
            msg: err.message,
            data: null,
        });
    }

    // 2. 处理5xx服务端错误（需要日志+告警）
    const clientIp = req.ip || req.connection.remoteAddress; // 客户端IP
    const requestParams = JSON.stringify({ body: req.body, query: req.query, params: req.params }, null, 2); // 格式化请求参数
    const userAgent = req.headers['user-agent'] || '未知'; // 浏览器/客户端信息
    const errorStack = err.stack?.substring(0, 800) + (err.stack?.length > 800 ? '...' : ''); // 截取堆栈（避免过长）

    // 打印详细错误日志
    logger.error(
        `${color.red}❌ 接口服务端异常：
            请求路径：${req.path}
            请求方法：${req.method}
            客户端IP：${clientIp}
            请求参数：${requestParams}
            浏览器信息：${userAgent}
            错误详情：${err.message}
            错误堆栈：${errorStack}
        ${color.reset}`,
        { metadata: {} },
    );

    // 3. 生产环境发送告警邮件（非阻塞，不影响响应）
    // if (NODE_ENV === 'production' && ALERT_EMAILS.length > 0) {
    if (ALERT_EMAILS.length > 0) {
        const alertContent = `
            <p style="color: #d32f2f; font-size: 16px; font-weight: bold;">🚨 [重要] CorpHR接口服务端异常（500）</p>
            <p>📅 时间：${new Date().toLocaleString()}</p>
            <p>🌍 环境：${NODE_ENV}</p>
            <p>📍 请求路径：${req.path}</p>
            <p>🔧 请求方法：${req.method}</p>
            <p>🌐 客户端IP：${clientIp}</p>
            <p>📋 请求参数：<pre style="background: #f5f5f5; padding: 8px; border-radius: 4px;">${requestParams}</pre></p>
            <p>🖥️  浏览器信息：${userAgent}</p>
            <p>❌ 错误详情：${err.message}</p>
            <p>📜 错误堆栈：<pre style="background: #f5f5f5; padding: 8px; border-radius: 4px; color: #d32f2f;">${errorStack}</pre></p>
            <p>⚠️  影响：该接口功能不可用，可能影响相关业务流程</p>
            <p>💡 解决方案：根据错误堆栈排查接口代码逻辑（重点看报错行附近）</p>
        `;

        // 给所有告警接收人发送邮件（非阻塞）
        ALERT_EMAILS.forEach((email) => {
            emailTool
                .sendNotice(
                    email.trim(), // 去除邮箱前后空格（避免配置错误）
                    '[重要] CorpHR接口500异常告警',
                    alertContent,
                )
                .catch((mailErr) => {
                    // 捕获邮件发送失败的错误（不影响主流程）
                    logger.error(
                        `${color.red}❌ 接口异常告警邮件发送失败（收件人：${email}）：${mailErr.message}${color.reset}`,
                        { metadata: {} },
                    );
                });
        });
    }

    // 4. 给前端返回统一的500错误响应
    res.status(500).json({
        code: 500,
        msg: '服务器内部错误，请稍后重试',
        data: null,
    });
};

module.exports = errorHandler;
